package com.googlecode.mavenfilesync;

import java.util.Collection;

import com.googlecode.mavenfilesync.FileSyncSetupMojo.Param;

public class SettingsBuilder {

	private static final String NEW_LINE = System.getProperty("line.separator");
	private final StringBuilder settings;

	/**
	 * Used when creating mapping to verify mapping correctness: no default
	 * value for directory output is accepted if there is no default global
	 * output.
	 */
	private boolean defaultDestinationGiven = false;

	/**
	 * Mappings in the settings file get consecutive numbers, starting from
	 * zero. This variable is used to calculate correct mapping index.
	 */
	private int mappingsCount = 0;

	public SettingsBuilder() {
		settings = new StringBuilder(
				"WARNING=DO NOT MODIFY THIS FILE IF YOU DON'T UNDERSTAND")
				.append(NEW_LINE);
	}

	public SettingsBuilder with(final Param name, final boolean value) {
		return with(name, String.valueOf(value));
	}

	public SettingsBuilder with(final Param name, final String value) {
		if (Param.DEFAULT_DESTINATION.equals(name) && (value.length() > 0)) {
			defaultDestinationGiven = true;
		}
		settings.append(name).append("=").append(value).append(NEW_LINE);
		return this;
	}

	public SettingsBuilder withMapping(final FileSyncMapping mapping) {
		if (((mapping.getDestinationFolder() == null)
				|| (mapping.getDestinationFolder().length() == 0) || FileSyncMapping.MAPPING_EMPTY_VALUE
				.equals(mapping.getDestinationFolder()))
				&& !defaultDestinationGiven) {
			throw new IllegalArgumentException(
					"Mapping destination folder has to be given if no default destination has been specified.");
		}
		if (mapping.getSourceFolder().length() == 0) {
			throw new IllegalArgumentException(
					"The source folder has to be given for every mapping.");
		}

		settings.append(new MappingBuilder(mappingsCount).withMapping(mapping)
				.build());
		mappingsCount++;
		return this;
	}

	public String build() {
		return settings.toString();
	}

	private static class MappingBuilder {

		final StringBuilder mappingBuilder;

		public MappingBuilder(final int index) {
			mappingBuilder = new StringBuilder("map|").append(index)
					.append("=");
		}

		public MappingBuilder withMapping(final FileSyncMapping mapping) {
			mappingBuilder.append(mapping.getSourceFolder()).append("|");
			mappingBuilder.append(mapping.getDestinationFolder()).append("|");

			mappingBuilder.append(
					semicolonSeparatedCollection(mapping.getInclPatternList()))
					.append("|");

			mappingBuilder.append(
					semicolonSeparatedCollection(mapping.getExclPatternList()))
					.append("|");

			mappingBuilder.append(mapping.getVariablesFile()).append(NEW_LINE);
			return this;
		}

		private StringBuilder semicolonSeparatedCollection(
				final Collection<String> collection) {
			final StringBuilder builder = new StringBuilder();

			for (final String element : collection) {
				builder.append(element).append(";");
			}
			// Removing trailing semicolon after the last element
			builder.deleteCharAt(builder.length() - 1);
			return builder;
		}

		public String build() {
			return this.mappingBuilder.toString();
		}

	}
}